package com.jcl.cloud.services.crawler.catchnew.service;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class ThreadMonitorService {


    private static Logger logger = LoggerFactory.getLogger(ThreadMonitorService.class);

    @Autowired
    private RedisService redisService;

    private Map<String, Thread> runningTasks = new ConcurrentHashMap<>();
    private Map<String, Long> startRecords = new ConcurrentHashMap<>();
    private Long EXECUTE_OVERTIME = (long) (30 * 60 * 1000);

    @Scheduled(
            fixedRate = 30000L
    )
    public void delayMonitor() {
        logger.info("开始执行定时线程监控任务...");
        for (String key : runningTasks.keySet()) {

            logger.info("正在被监控的任务号：" + key);
            try {
                Thread t = runningTasks.get(key);
                Long startTime = this.startRecords.get(key);
                Long cTime = System.currentTimeMillis();

                Long runningTime = (cTime - startTime) /1000;
                boolean isAlive = this.isThreadAlive(key,t);

                if ((cTime - startTime) > this.EXECUTE_OVERTIME) {
                    if (isAlive) {
                        try {
                            t.stop();
                        } catch (Exception e) {
                            logger.error(String.format("超时任务号：%s  关闭发生异常：%s",key,e.getMessage()),e);
                        }
                        this.reportTask(key);
                    }
                    this.clearTask(key);
                    logger.info(String.format("执行超时的任务号：%s",key));
                }else {

                    if(isAlive){
                        //打印运行时长
                        logger.info(String.format("正在运行的任务号：%s   已经运行的时长为：%s秒",key,String.valueOf(runningTime)));
                    }else {
                        this.clearTask(key);
                    }
                }
            } catch (Exception e) {
                logger.error(String.format("任务号：%s   线程状况判断发生异常：%s",key,e.getMessage()),e);
            }
        }

        logger.info("定时线程监控任务执行结束...");
    }





    public void execute(Runnable command, String id) {

        Thread thread = new Thread(command);
        thread.start();
        Long cTime = System.currentTimeMillis();
        this.startRecords.put(id + "@=" + thread.getName(), cTime);
        this.runningTasks.put(id + "@=" + thread.getName(), thread);
    }


    private void clearTask(String key) {
        logger.info("监控服务移除的任务号为：" + key);
        this.runningTasks.remove(key);
        this.startRecords.remove(key);
    }


    private void reportTask(String id) {
        String crawlerId = id.split("@=")[0];
        this.redisService.lpush("unicrawler:tasks:all", crawlerId);
        logger.info("监控服务上报的任务号为：" + crawlerId);
    }


    private boolean isThreadAlive(String key,Thread t){

        boolean flag = false;

        try {
            if(t.isAlive()){
                flag = true;
            }
        } catch (Exception e) {
            logger.info(String.format("判断线程号为：%s   是否还活着发生异常；%s",key,e.getMessage()),e);
        }

        return flag;
    }
}
